/**
 * 权限控制组件
 * 将对当前用户拥有的权限进行校验，如果没有，则渲染null
 */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'dva';
import config from '../configs/config';

// 对children进行权限控制，支持两种模式，
// 一种是默认模式default，给当前组件传入权限url，对children进行权限控制
// 第二种是permissionUrl模式，给children的props增加一个permissionUrl，将会递归对所有children以及children的children进行权限控制
// 使用permissionUrl模式时可以使用level对递归最大深度进行指定，以优化性能
class PermissionControl extends Component {
	permissionControl(urls, children) {
		const { permissionList = [], } = this.props;
		if (!urls) return children;
		if (!Array.isArray(urls)) urls = [urls];// 与操作
		urls = urls.map(url => apiPrefix(url));
		return urls.every(url => permissionList.find(p => p.uri === url)) ? children : null;
	}

	taverseChildren(children, level) {
		const l = level - 1;
		if (level <= 0) return children;
		if (Array.isArray(children)) {
			return children.map(c => this.taverseChildren(c, l));
		} else if (typeof children === 'object') {
			const { props: { permissionUrl, children: pChildren } } = children;
			let com = this.permissionControl(permissionUrl, children);
			if (com) {
				try {
					com = React.cloneElement(com);
					com.props.children = this.taverseChildren(pChildren, l);
				} catch (error) {
					console.error('该props的children赋值错误', error);
				}
			}
			return com;
		} else return children;
	}

	render() {
		const { url, children, mode, level = 1000 } = this.props;
		switch (mode) {
			case 'permissionUrl': // 从每一个元素的props里面找permissionUrl作为权限url进行对比
				return this.taverseChildren(children, level + 1);
			case 'default':
			default:
				return this.permissionControl(url, children);
		}
	}
}

PermissionControl.propTypes = {
	url: PropTypes.string,
	mode: PropTypes.string,
	level: PropTypes.number
};

// 开发环境下替换掉api前缀
export function apiPrefix(url) {
	if (!url) return url;
	return config.apiPrefix ? url.replace(config.apiPrefix, '') : url;
}

export function inPermissionList(permissionList, children) {
	if (!permissionList || !permissionList.length || !children || !children.length) return [];
	return children.map(c => getPermission(permissionList, c.url) ? c.com : null);
}

export function getPermission(permissionList, url) {
	url = apiPrefix(url);
	if (!permissionList || !permissionList.length) return;
	return permissionList.find(p => p.uri === url);
}

// 版本代码
export const version = {
	boliwei: 'boliwei',
	release: '1.0',
};

// 判断不同版本号显示隐藏对应的字段
export function isVersion(permissionList = [], url, version, opt = {}) {
	const p = getPermission(permissionList, url);
	if (!p) return false;
	const s = permissionList.find(v => !v.uri && v.pPermissionId === p.id);
	if (!s) return false;
	if (!s.versionCode && opt.orNull) return true;
	if (s.versionCode === version) return true;
	return false;
}
export function isReleaseVersion(permissionList = [], url) {
	return isVersion(permissionList, url, '1.0', { orNull: true });
}
export function isBoliweiVersion(permissionList = [], url) {
	return isVersion(permissionList, url, 'boliwei');
}

export default connect(({ app }) => ({ permissionList: app.user.permissions }))(PermissionControl);
